
! <compile=optimized>
#include "copyright.h"
#define _REAL_ double precision
#include "pb_def.h"

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!+ Driver of direct coulombic and vdw energy and force
subroutine pb_directnocut( natom,proatm,inatm,ipres,ibgwat,ienwat,ibgion,ienion,ntypes,eneopt, &
                           idecomp,ifcap,iac,ico,nex,iex,cn1,cn2,cg,x,f,eel,enb )
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !
   ! Authors:
   ! Lijiang Yang, Luo Research Group, UC-Irvine
   !
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
   implicit none

#  include "pb_constants.h"
#  include "flocntrl.h"
    
   ! Passed variables
    
   integer natom, proatm, inatm, ibgwat, ienwat, ibgion, ienion, ntypes, eneopt, idecomp, ifcap
   integer ipres(*), iac(*), ico(*), nex(natom), iex(64,natom)
   _REAL_ cn1(*), cn2(*), cg(natom)
   _REAL_ x(3,natom)
   _REAL_ enb, eel, f(3,natom)
    
   ! Local variables
    
   integer iaci, ic, watres, watfirst, ionfirst
   _REAL_ cn1oo, cn2oo, cgoo, cgoh, cghh
   _REAL_ eelwat, enbwat, eelpro, enbpro, eelprowat, enbprowat
    
   if ( do_pbdir == 0 ) return

   eelwat = ZERO; enbwat = ZERO
   eelpro = ZERO; enbpro = ZERO
   eelprowat = ZERO; enbprowat = ZERO

   if ( ibgwat /= 0 ) then
      proatm = ipres(ibgwat) - 1
   else
      proatm = natom
   end if

   if((ifcap == 2 .or. ifcap == 5) .and. proatm > inatm) then
      write(6, *) 'PB bomb in pb_directnocut(): proatm must not be larger than inatm here'
      call mexit(6, 1)
   end if

   watfirst = 0
   watres = 0
   ionfirst = 0
   if ( ibgwat /= 0 ) then
      watfirst = proatm + 1
      if(ifcap == 2 .or. ifcap == 5) then
         watres = (inatm - watfirst + 1) / 3
      else
         watres = ienwat - ibgwat + 1
      end if
      if( ibgion /= 0) then
        ionfirst = ipres(ibgion)
      endif
   end if
    
   ! get protein/protein and protein/water interactions
    
   call pb_dirpro(proatm,natom,watres,watfirst,ionfirst,ntypes,ifcap,nex,iex,iac,ico,cn1,cn2,cg,x,f, &
                  eelpro,enbpro,eelprowat,enbprowat)

   if(ifcap == 2 .or. ifcap == 5) then
      write(6,'(a,2f10.3)') ' Protein-solvent interactions: ', eelprowat, enbprowat
   end if
    
   ! get water/water interactions
   ! first get van der Waals and charge-charge pairs
    
   if ( ibgwat /= 0 ) then
      iaci = ntypes*(iac(watfirst)-1)
      ic = ico(iaci+iac(watfirst))
      cn1oo = cn1(ic); cn2oo = cn2(ic)
      cgoo = cg(watfirst)**2
      cgoh = cg(watfirst)*cg(watfirst+1)
      cghh = cg(watfirst+1)**2
      call pb_dirwat(watfirst,watres,ibgwat,ienwat,cn1oo,cn2oo,cgoo,cgoh,cghh,x,f,eelwat,enbwat)
   end if
    
   eel = eelwat + eelpro + eelprowat
   enb = enbwat + enbpro + enbprowat
    
contains
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!+ compute direct non-water/all nonbonded interactions
subroutine pb_dirpro( proatm,natom,watres,watfirst,ionfirst,ntypes,ifcap,nex,iex,iac,ico,cn1,cn2,cg,x,f, &
                      eelpro,enbpro,eelprowat,enbprowat )
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !
   ! Authors:
   ! Lijiang Yang, Luo Research Group, UC-Irvine
   !
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   use poisson_boltzmann, only: outflag
   use decomp, only: decpair
    
   implicit none

#  include "pb_constants.h"
    
   ! Passed variables
    
   integer proatm, natom, watres, watfirst, ionfirst, ntypes, ifcap
   integer iac(*), ico(*), nex(natom), iex(64, natom)
   _REAL_ cn1(*), cn2(*), cg(natom)
   _REAL_ x(3,natom)
   _REAL_ eelpro, enbpro, eelprowat, enbprowat, f(3,natom)
    
   ! Local variables
    
   integer jex,i,j,ilast,jfirst,jlast,iaci,ic,jp,iatm
   _REAL_ cgi,cgj,cn1ij,cn2ij,cgio,cgih,cn1io,cn2io
   _REAL_ dumx,dumy,dumz,xi,yi,zi,dx,dy,dz,d2inv,r6
   _REAL_ f1,f2,df,df2,fw1,fw2,fw3
   _REAL_ eelprotmp, enbprotmp, eelprowattmp, enbprowattmp
   _REAL_ xwij1(3*watres), xwij2(3*watres), xwij3(3*watres), rw1(3*watres)
   _REAL_ fx(3*watres), fy(3*watres), fz(3*watres)
   _REAL_ coulx(natom),couly(natom),coulz(natom)
   _REAL_ vdwx(natom),vdwy(natom),vdwz(natom)
   _REAL_ ofx(natom),ofy(natom),ofz(natom)

    
   ! Compute interaction energy and forces for non-water atoms 
    
   vdwx = ZERO; vdwy=ZERO; vdwz=ZERO
   coulx = ZERO; couly=ZERO; coulz=ZERO
   ofx = f(1,1:natom); ofy = f(2,1:natom); ofz = f(3,1:natom)

   ilast = proatm
   do i = 1, ilast
      if((ifcap == 2 .or. ifcap == 5) .and. outflag(i) == 1) cycle
      iaci = ntypes*(iac(i)-1); cgi = cg(i)
      xi = x(1,i); yi = x(2,i); zi = x(3,i)
      dumx = ZERO; dumy = ZERO; dumz = ZERO
      eelprotmp = ZERO; enbprotmp = ZERO
      eelprowattmp = ZERO; enbprowattmp = ZERO
       
      ! pro/pro interactions
       
      do j = i+1, ilast
         if((ifcap == 2 .or. ifcap == 5) .and. outflag(j) == 1) cycle
         do jp = 1, nex(i)
            jex = iex(jp,i)
            if (j == jex) goto 10
         end do
         dx = xi - x(1,j); dy = yi - x(2,j); dz = zi - x(3,j); cgj=cg(j)
         d2inv = ONE/(dx**2+dy**2+dz**2)
         df2 = -cgi*cgj*sqrt(d2inv)
         if(i < ionfirst .and. j >= ionfirst) then
            ! Count protein <-> ion interactions separately
            eelprowattmp = eelprowattmp + df2
         else
            eelprotmp = eelprotmp + df2
         end if
         ic = ico(iaci+iac(j)); cn1ij = cn1(ic); cn2ij = cn2(ic)
         r6 = d2inv**3; f2 = cn2ij*r6; f1 = cn1ij*(r6*r6)
         if(i < ionfirst .and. j >= ionfirst) then
            ! Count protein <-> ion interactions separately
            enbprowattmp = enbprowattmp + (f2-f1)
         else
            enbprotmp = enbprotmp + (f2-f1)
         end if

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            if(eneopt == 1) then
               call decpair(1,i,j,df2)
            end if
            call decpair(2,i,j,-df2)
            call decpair(3,i,j,(f1 - f2))
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-2,i,j,-df2)
            call decpair(-3,i,j,(f1 - f2))
         end if

         df = ( df2 + SIX*( (f2-f1)-f1 ) )*d2inv
         fw1 = dx*df; fw2 = dy*df; fw3 = dz*df
         dumx = dumx + fw1
         dumy = dumy + fw2
         dumz = dumz + fw3
         f(1,j) = f(1,j) + fw1
         f(2,j) = f(2,j) + fw2
         f(3,j) = f(3,j) + fw3

         ! for "waterless" only
         df = df2*d2inv
         fw1 = dx*df; fw2 = dy*df; fw3 = dz*df
         coulx(j) = coulx(j) + fw1
         couly(j) = couly(j) + fw2
         coulz(j) = coulz(j) + fw3
         coulx(i) = coulx(i) - fw1
         couly(i) = couly(i) - fw2
         coulz(i) = coulz(i) - fw3
         df = SIX*( (f2-f1)-f1 )*d2inv
         fw1 = dx*df; fw2 = dy*df; fw3 = dz*df
         vdwx(j) = vdwx(j) + fw1
         vdwy(j) = vdwy(j) + fw2
         vdwz(j) = vdwz(j) + fw3
         vdwx(i) = vdwx(i) - fw1
         vdwy(i) = vdwy(i) - fw2
         vdwz(i) = vdwz(i) - fw3
 
10       continue
      end do
       
      ! pro/wat interactions
       
      if ( watres /= 0 ) then
       
      ic = ico(iaci+iac(watfirst)); cn1io = cn1(ic); cn2io = cn2(ic)
      cgio = cgi*cg(watfirst); cgih = cgi*cg(watfirst+1)
       
      ! stacking i <-> ow
       
      j = watfirst
      jfirst = 1; jlast = watres
      do jp = jfirst, jlast
         xwij1(jp) = xi - x(1,j); xwij2(jp) = yi - x(2,j); xwij3(jp) = zi - x(3,j)
         j = j + 3
      end do
       
      ! stacking i <-> hw1
       
      j = watfirst + 1
      jfirst = watres+1; jlast = 2*watres
      do jp = jfirst, jlast
         xwij1(jp) = xi - x(1,j); xwij2(jp) = yi - x(2,j); xwij3(jp) = zi - x(3,j)
         j = j + 3
      end do
       
      ! stacking i <-> hw2
       
      j = watfirst + 2
      jfirst = 2*watres+1; jlast = 3*watres
      do jp = jfirst, jlast
         xwij1(jp) = xi - x(1,j); xwij2(jp) = yi - x(2,j); xwij3(jp) = zi - x(3,j)
         j = j + 3
      end do
       
      do jp = 1, 3*watres
         rw1(jp) = ONE/( xwij1(jp)**2 + xwij2(jp)**2 + xwij3(jp)**2 )
      end do
       
      ! compute forces for i <-> ow
       
      jfirst = 1; jlast = watres
!c !DIR$ IVDEP
      do jp = jfirst, jlast
         df2 = -cgio*sqrt(rw1(jp))
         eelprowattmp = eelprowattmp + df2
         r6 = rw1(jp)**3; f2 = cn2io*r6; f1 = cn1io*(r6*r6)
         enbprowattmp = enbprowattmp + (f2-f1)

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            if(eneopt == 1) then
               call decpair(1,i,j,df2)
            end if
            call decpair(2,i,j,-df2)
            call decpair(3,i,j,(f1 - f2))
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-2,i,j,-df2)
            call decpair(-3,i,j,(f1 - f2))
         end if

         df = ( df2+SIX*( (f2-f1)-f1 ) )*rw1(jp)
         fw1 = xwij1(jp)*df; fw2 = xwij2(jp)*df; fw3 = xwij3(jp)*df
         dumx = dumx + fw1
         dumy = dumy + fw2
         dumz = dumz + fw3
         fx(jp) = fw1
         fy(jp) = fw2
         fz(jp) = fw3
      end do
       
      ! compute forces for i <-> hw1, hw2
       
      jfirst = watres+1; jlast = 3*watres
!c !DIR$ IVDEP
      do jp = jfirst, jlast
         df2 = -cgih*sqrt(rw1(jp))
         eelprowattmp = eelprowattmp + df2

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            if(eneopt == 1) then
               call decpair(1,i,j,df2)
            end if
            call decpair(2,i,j,-df2)
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-2,i,j,-df2)
         end if

         df = ( df2 )*rw1(jp)
         fw1 = xwij1(jp)*df; fw2 = xwij2(jp)*df; fw3 = xwij3(jp)*df
         dumx = dumx + fw1
         dumy = dumy + fw2
         dumz = dumz + fw3
         fx(jp) = fw1
         fy(jp) = fw2
         fz(jp) = fw3
      end do
       
      ! collecting forces
       
      j = watfirst
!c !DIR$ IVDEP
      do jp = 1, watres
         f(1,j  ) = f(1,j  ) + fx(         jp)
         f(2,j  ) = f(2,j  ) + fy(         jp)
         f(3,j  ) = f(3,j  ) + fz(         jp)
         f(1,j+1) = f(1,j+1) + fx(  watres+jp)
         f(2,j+1) = f(2,j+1) + fy(  watres+jp)
         f(3,j+1) = f(3,j+1) + fz(  watres+jp)
         f(1,j+2) = f(1,j+2) + fx(2*watres+jp)
         f(2,j+2) = f(2,j+2) + fy(2*watres+jp)
         f(3,j+2) = f(3,j+2) + fz(2*watres+jp)
         j = j + 3
      end do
       
      end if
       
      eelpro = eelpro - eelprotmp; enbpro = enbpro - enbprotmp
      eelprowat = eelprowat - eelprowattmp; enbprowat = enbprowat - enbprowattmp
       
      f(1,i) = f(1,i) - dumx
      f(2,i) = f(2,i) - dumy
      f(3,i) = f(3,i) - dumz
   end do  ! i = 1, ilast

!  open (unit = 107, file = 'coul.dat')

!  write(107,*) ' :::: Coulombic forces ::::'
!  do iatm = 1, natom
!     write(107,'(3e20.6)') coulx(iatm),couly(iatm),coulz(iatm)
!  end do

!  open (unit = 108, file = 'vdw.dat')

!  write(108,*) ' :::: Van der Waals forces ::::'
!  do iatm = 1, natom
!     write(108,'(3e20.6)') vdwx(iatm),vdwy(iatm),vdwz(iatm)
!  end do
!   
!  open (unit = 109, file = 'dir.dat')

!  write(109,*) ' :::: Direct forces ::::' 
!  do iatm = 1, natom
!     write(109,'(3e20.6)') f(1,iatm)-ofx(iatm),f(2,iatm)-ofy(iatm),f(3,iatm)-ofz(iatm)
!  end do

end subroutine pb_dirpro
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!+ compute direct water/water nonbonded forces 
subroutine pb_dirwat( watfirst,watres,ibgwat,ienwat,cn1oo,cn2oo,cgoo,cgoh,cghh,x,f,eelwat,enbwat )
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !
   ! Authors:
   ! Lijiang Yang, Luo Research Group, UC-Irvine
   !
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
   implicit none
    
#  include "pb_constants.h"

   ! Passed variables
    
   integer watfirst, watres, ibgwat, ienwat
   _REAL_ cn1oo, cn2oo, cgoo, cgoh, cghh
   _REAL_ x(3,*)
   _REAL_ eelwat, enbwat, f(3,*)
    
   ! Local variables
    
   integer i,j,ii,jj,jn,ni,ilast,natmo,jo,jh1,jh2
   _REAL_ dfa,dfb,dfc,r6,f1,f2,fw1,fw2,fw3,fw4,fw5,fw6,fw7,fw8,fw9
   _REAL_ dumxa,dumya,dumza,dumxb,dumyb,dumzb,dumxc,dumyc,dumzc
   _REAL_ xo1, xo2, xo3, xa1, xa2, xa3, xb1, xb2, xb3
   _REAL_ eelwattmp,enbwattmp
   _REAL_ xwij1(3*watres),xwij2(3*watres),xwij3(3*watres)
   _REAL_ xwij4(3*watres),xwij5(3*watres),xwij6(3*watres)
   _REAL_ xwij7(3*watres),xwij8(3*watres),xwij9(3*watres)
   _REAL_ rw1(3*watres),rw2(3*watres),rw3(3*watres)
   _REAL_ fx(3*watres),fy(3*watres),fz(3*watres)
    
   ilast = ibgwat + watres - 1
   natmo = watres   ! the number of water's oxygen atoms
   ni    = 1        ! ni is the counter of waters that have been considered
                    ! for every ii increment, it is incremented by 1
   i = watfirst - 3 ! the first water oxygen - 3
   do ii = ibgwat, ilast-1
       
      ! get the distances between each water(i)'s (O,H1,H2) and O(j). xwij(1:3,*): for pairs
      ! of O(i) and O(j); xwij(4:6,*): for H1(i) and O(j); xwji(7:9,*): for H2(i) and O(j).
      ! do the same for H1(j) and H2(j). the number of water(i)-O(j) pairs is natmo-ni.
      ! this is also the case for water(i)-H1(j) and for water(i)-H2(j).
       
      i = i + 3; jn = 1  ! jn is index of atom pairs
      xo1 = x(1,i  ); xo2 = x(2,i  ); xo3 = x(3,i  )
      xa1 = x(1,i+1); xa2 = x(2,i+1); xa3 = x(3,i+1)
      xb1 = x(1,i+2); xb2 = x(2,i+2); xb3 = x(3,i+2)
       
      jo = i; jh1 = i + 1; jh2 = i + 2
      do jj = ii+1, ilast
         jo = jo + 3
         xwij1(jn) = xo1 - x(1,jo)
         xwij2(jn) = xo2 - x(2,jo)
         xwij3(jn) = xo3 - x(3,jo)
         xwij4(jn) = xa1 - x(1,jo)
         xwij5(jn) = xa2 - x(2,jo)
         xwij6(jn) = xa3 - x(3,jo)
         xwij7(jn) = xb1 - x(1,jo)
         xwij8(jn) = xb2 - x(2,jo)
         xwij9(jn) = xb3 - x(3,jo)
         jn = jn + 1
      end do
      do jj = ii+1, ilast
         jh1 = jh1 + 3
         xwij1(jn) = xo1 - x(1,jh1)
         xwij2(jn) = xo2 - x(2,jh1)
         xwij3(jn) = xo3 - x(3,jh1)
         xwij4(jn) = xa1 - x(1,jh1)
         xwij5(jn) = xa2 - x(2,jh1)
         xwij6(jn) = xa3 - x(3,jh1)
         xwij7(jn) = xb1 - x(1,jh1)
         xwij8(jn) = xb2 - x(2,jh1)
         xwij9(jn) = xb3 - x(3,jh1)
         jn = jn + 1
      end do
      do jj = ii+1, ilast
         jh2 = jh2 + 3
         xwij1(jn) = xo1 - x(1,jh2)
         xwij2(jn) = xo2 - x(2,jh2)
         xwij3(jn) = xo3 - x(3,jh2)
         xwij4(jn) = xa1 - x(1,jh2)
         xwij5(jn) = xa2 - x(2,jh2)
         xwij6(jn) = xa3 - x(3,jh2)
         xwij7(jn) = xb1 - x(1,jh2)
         xwij8(jn) = xb2 - x(2,jh2)
         xwij9(jn) = xb3 - x(3,jh2)
         jn = jn + 1
      end do
      do j = 1, jn
         rw1(j) = ONE/( xwij1(j)**2 + xwij2(j)**2 + xwij3(j)**2 )
         rw2(j) = ONE/( xwij4(j)**2 + xwij5(j)**2 + xwij6(j)**2 )
         rw3(j) = ONE/( xwij7(j)**2 + xwij8(j)**2 + xwij9(j)**2 )
      end do
       
      ! compute the energy and force of the oxygen atom for water(i)
      ! if the ni'th water is under consideration, water after it will be natmo-ni
       
      eelwattmp = ZERO; enbwattmp = ZERO

      dumxa = ZERO; dumya = ZERO; dumza = ZERO
      dumxb = ZERO; dumyb = ZERO; dumzb = ZERO
      dumxc = ZERO; dumyc = ZERO; dumzc = ZERO
!c !DIR$ IVDEP
      do jn = 1, natmo-ni
         dfa = -cgoo*sqrt(rw1(jn))
         dfb = -cgoh*sqrt(rw2(jn))
         dfc = -cgoh*sqrt(rw3(jn))
         eelwattmp = eelwattmp + dfa+dfb+dfc
          
         r6 = rw1(jn)**3
         f2 = cn2oo*r6
         f1 = cn1oo*(r6*r6)
         enbwattmp = enbwattmp + (f2-f1)
          
         dfa = (dfa+SIX*((f2-f1)-f1))*rw1(jn)
         dfb = dfb*rw2(jn)
         dfc = dfc*rw3(jn)
          
         fw1 = xwij1(jn)*dfa
         fw2 = xwij2(jn)*dfa
         fw3 = xwij3(jn)*dfa
         fw4 = xwij4(jn)*dfb
         fw5 = xwij5(jn)*dfb
         fw6 = xwij6(jn)*dfb
         fw7 = xwij7(jn)*dfc
         fw8 = xwij8(jn)*dfc
         fw9 = xwij9(jn)*dfc
            
         dumxa = dumxa + fw1
         dumya = dumya + fw2
         dumza = dumza + fw3
         dumxb = dumxb + fw4
         dumyb = dumyb + fw5
         dumzb = dumzb + fw6
         dumxc = dumxc + fw7
         dumyc = dumyc + fw8
         dumzc = dumzc + fw9
            
         fx(jn) = fw1+fw4+fw7
         fy(jn) = fw2+fw5+fw8
         fz(jn) = fw3+fw6+fw9
      end do  !  jn = 1, natmo-ni 
        
      ! compute the energy and force of H1 and H2 atoms of water(i)
      ! there is natmo-ni water(i)-o(j) pairs, so H1 pairs will be from natmo-ni+1 to 2*(natmo-ni)
        
!c !DIR$ IVDEP
      do jn = natmo-ni+1, 2*(natmo-ni)
         dfa = -cgoh*sqrt(rw1(jn))
         dfb = -cghh*sqrt(rw2(jn))
         dfc = -cghh*sqrt(rw3(jn))
         eelwattmp = eelwattmp + dfa+dfb+dfc
            
         dfa = dfa*rw1(jn)
         dfb = dfb*rw2(jn)
         dfc = dfc*rw3(jn)
            
         fw1 = xwij1(jn)*dfa
         fw2 = xwij2(jn)*dfa
         fw3 = xwij3(jn)*dfa
         fw4 = xwij4(jn)*dfb
         fw5 = xwij5(jn)*dfb
         fw6 = xwij6(jn)*dfb
         fw7 = xwij7(jn)*dfc
         fw8 = xwij8(jn)*dfc
         fw9 = xwij9(jn)*dfc
            
         dumxa = dumxa + fw1
         dumya = dumya + fw2
         dumza = dumza + fw3
         dumxb = dumxb + fw4
         dumyb = dumyb + fw5
         dumzb = dumzb + fw6
         dumxc = dumxc + fw7
         dumyc = dumyc + fw8
         dumzc = dumzc + fw9
            
         fx(jn) = fw1+fw4+fw7
         fy(jn) = fw2+fw5+fw8
         fz(jn) = fw3+fw6+fw9
      end do  !  jn = natmo-ni+1, 2*(natmo-ni) 
        
!c !DIR$ IVDEP
      do jn = 2*(natmo-ni)+1, 3*(natmo-ni)
         dfa = -cgoh*sqrt(rw1(jn))
         dfb = -cghh*sqrt(rw2(jn))
         dfc = -cghh*sqrt(rw3(jn))
         eelwattmp = eelwattmp + dfa+dfb+dfc
            
         dfa = dfa*rw1(jn)
         dfb = dfb*rw2(jn)
         dfc = dfc*rw3(jn)
            
         fw1 = xwij1(jn)*dfa
         fw2 = xwij2(jn)*dfa
         fw3 = xwij3(jn)*dfa
         fw4 = xwij4(jn)*dfb
         fw5 = xwij5(jn)*dfb
         fw6 = xwij6(jn)*dfb
         fw7 = xwij7(jn)*dfc
         fw8 = xwij8(jn)*dfc
         fw9 = xwij9(jn)*dfc
            
         dumxa = dumxa + fw1
         dumya = dumya + fw2
         dumza = dumza + fw3
         dumxb = dumxb + fw4
         dumyb = dumyb + fw5
         dumzb = dumzb + fw6
         dumxc = dumxc + fw7
         dumyc = dumyc + fw8
         dumzc = dumzc + fw9
            
         fx(jn) = fw1+fw4+fw7
         fy(jn) = fw2+fw5+fw8
         fz(jn) = fw3+fw6+fw9
      end do  !  jn = 2*(natmo-ni)+1, 3*(natmo-ni)
       
      ! Now collecting forces ... for j's and i's
       
      jn = 1; j = i
!c !DIR$ IVDEP
      do jj = ii+1, ilast
         j = j + 3
         f(1,j  ) = f(1,j  ) + fx(             jn)
         f(2,j  ) = f(2,j  ) + fy(             jn)
         f(3,j  ) = f(3,j  ) + fz(             jn)
         f(1,j+1) = f(1,j+1) + fx(   natmo-ni +jn)
         f(2,j+1) = f(2,j+1) + fy(   natmo-ni +jn)
         f(3,j+1) = f(3,j+1) + fz(   natmo-ni +jn)
         f(1,j+2) = f(1,j+2) + fx(2*(natmo-ni)+jn)
         f(2,j+2) = f(2,j+2) + fy(2*(natmo-ni)+jn)
         f(3,j+2) = f(3,j+2) + fz(2*(natmo-ni)+jn)
         jn = jn + 1
      end do
       
      eelwat = eelwat - eelwattmp; enbwat = enbwat - enbwattmp
       
      f(1,i  ) = f(1,i  ) - dumxa
      f(2,i  ) = f(2,i  ) - dumya
      f(3,i  ) = f(3,i  ) - dumza
      f(1,i+1) = f(1,i+1) - dumxb
      f(2,i+1) = f(2,i+1) - dumyb
      f(3,i+1) = f(3,i+1) - dumzb
      f(1,i+2) = f(1,i+2) - dumxc
      f(2,i+2) = f(2,i+2) - dumyc
      f(3,i+2) = f(3,i+2) - dumzc
        
      ni = ni + 1
        
   end do  ! ii = ibgwat, ilast-1
    
    
end subroutine pb_dirwat

end subroutine pb_directnocut
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!+ pairwise nonbonded forces
subroutine pb_directwtcut( natom,atmlast,ifcap,idecomp,iprshrt,iar1pb,cn1pb,cn2pb,cn3pb,x,f,eel,enb )
    
   use poisson_boltzmann, only: outflag, ligand, multiblock, liveflag
   use decomp, only: decpair

   implicit none

#  include "pb_constants.h"
#  include "flocntrl.h"
    
   ! Passed variables
    
   integer natom, atmlast, ifcap, idecomp, iprshrt(*), iar1pb(4,0:natom)
   _REAL_ x(3,natom)
   _REAL_ cn1pb(*), cn2pb(*), cn3pb(*)
   _REAL_ f(3,natom)
   _REAL_ eel, enb
    
   ! Local variables
    
   integer i, j, jp, ilast, jfirst1, jlast1, jfirst2, jlast2
   _REAL_ xi, yi, zi
   _REAL_ dumx, dumy, dumz
   _REAL_ dx, dy, dz, d2inv, r6
   _REAL_ df2, f2, f1, df, fw1, fw2, fw3

   if ( do_pbdir == 0 ) return

   ! initialization
    
   eel     = ZERO; enb     = ZERO
   ilast   = atmlast - 1
   do i = 1, ilast
      if((ifcap == 2 .or. ifcap == 5) .and. outflag(i) == 1) cycle
      xi   = x(1,i); yi   = x(2,i); zi   = x(3,i)
       
      dumx = ZERO; dumy = ZERO; dumz = ZERO
       
      jfirst1 = iar1pb(1, i) + 1; jlast1 = iar1pb(2, i)
      jfirst2 = iar1pb(2, i) + 1; jlast2 = iar1pb(4, i)

      ! loop over direct coulombic pairs
       
!print *,"debug: jfirst1,jlast1,i",jfirst1,jlast1,i
      do jp = jfirst1, jlast1
         j = iprshrt(jp)
         if( j > atmlast ) cycle   ! Skip waters that should not be considered
         if((ifcap == 2 .or. ifcap == 5) .and. outflag(j) == 1 ) cycle   ! Skip ions that should not be considered
         if( multiblock ) then
             if( liveflag(j) == 0 ) cycle
         endif
         !if(multiblock .and. liveflag(j) == 0) cycle
         ! mjhsieh: in theory ligand should do the same thing, but it
         !          changes the result. please discuss.
         dx = xi - x(1,j); dy = yi - x(2,j); dz = zi - x(3,j)
         d2inv = ONE/(dx**2+dy**2+dz**2)
         df2 = cn3pb(jp)*sqrt(d2inv)
         eel = eel+df2

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            call decpair(2,i,j,-df2)
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-2,i,j,-df2)
         end if

         r6 = d2inv**3
         f2 = cn2pb(jp)*r6
         f1 = cn1pb(jp)*(r6*r6)
         enb = enb + (f2-f1)
         df = (df2+SIX*((f2-f1)-f1))*d2inv

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            call decpair(3,i,j,(f1 - f2))
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-3,i,j,(f1 - f2))
         end if

         fw1 = dx*df; fw2 = dy*df; fw3 = dz*df
         dumx = dumx + fw1
         dumy = dumy + fw2
         dumz = dumz + fw3
         f(1,j) = f(1,j) + fw1
         f(2,j) = f(2,j) + fw2
         f(3,j) = f(3,j) + fw3
      end do
       
      ! loop over nb pairs
       
!print *,"debug: jfirst1,jlast1,i",jfirst2,jlast2,i
      do jp = jfirst2, jlast2
         j = iprshrt(jp)
         if( j > atmlast ) cycle   ! Skip waters that should not be considered
         if((ifcap == 2 .or. ifcap == 5) .and. outflag(j) == 1) cycle   ! Skip ions that should not be considered
         if ( multiblock ) then
            if ( liveflag(j) == 0 ) cycle
         endif
         !if(multiblock .and. liveflag(j) == 0) cycle
         ! mjhsieh: in theory ligand should do the same thing, but it
         !          changes the result. please discuss.
         dx = xi - x(1,j); dy = yi - x(2,j); dz = zi - x(3,j)
         d2inv = ONE/(dx**2+dy**2+dz**2)
         r6 = d2inv**3
         f2 = cn2pb(jp)*r6
         f1 = cn1pb(jp)*(r6*r6)
         enb = enb + (f2-f1)
!print *,"debug: ENB =",enb,i,j
         df = SIX*((f2-f1)-f1)*d2inv

         !-- PB decomp
         if(idecomp == 1 .or. idecomp == 2) then
            call decpair(3,i,j,(f1 - f2))
         else if(idecomp == 3 .or. idecomp == 4) then
            call decpair(-3,i,j,(f1 - f2))
         end if

         fw1 = dx*df; fw2 = dy*df; fw3 = dz*df
         dumx = dumx + fw1
         dumy = dumy + fw2
         dumz = dumz + fw3
         f(1,j) = f(1,j) + fw1
         f(2,j) = f(2,j) + fw2
         f(3,j) = f(3,j) + fw3
      end do
!print *,"debug: EEL =",eel,i
!print *,"debug: ENB =",enb,i
      f(1,i) = f(1,i) - dumx
      f(2,i) = f(2,i) - dumy
      f(3,i) = f(3,i) - dumz
   end do  !  i = 1, ilast
 
   ! --- END OF PAIRS INVOLVING ATOM I ---
 
   eel = -eel; enb = -enb
 
end subroutine pb_directwtcut
